package qualomelhor.game;

import java.util.LinkedList;
import qualomelhor.gwt.modules.client.Callable;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import playn.core.Font;
import playn.core.GroupLayer;
import playn.core.PlayN;
import pythagoras.f.Rectangle;
import static playn.core.PlayN.graphics;
import tripleplay.game.ScreenStack;
import tripleplay.game.UIAnimScreen;
import tripleplay.ui.Background;
import tripleplay.ui.Button;
import tripleplay.ui.Field;
import tripleplay.ui.Group;
import tripleplay.ui.Label;
import tripleplay.ui.Root;
import tripleplay.ui.SimpleStyles;
import tripleplay.ui.Style;
import tripleplay.ui.Styles;
import tripleplay.ui.Stylesheet;
import tripleplay.ui.layout.AxisLayout;

public class TextAvatar extends UIAnimScreen {

	public static final Font TITLE_FONT = graphics().createFont("Helvetica", Font.Style.PLAIN, 12);
	private static final int tempoDisparaFadeOut = 10000; //10 seg 
	private static final int tempoParaSoletar = 50; //10 mili seg

    protected final ScreenStack _stack;
    protected Root _root;
    public Button back;
    public String text = "Ola!";
    public Label lb;
    //public Field lb;
    public tripleplay.ui.Field field;
    public Timer timerShow;
    public GroupLayer gLayerBalao;
    private boolean hideOnTime = false;
    private boolean isVisible = false;
	private final int menorTempoFade = 20;
	private final int maiorTempoFade = 80;
	private int tempoUltimaMessagem = 0;
	private int posX = 416;
	private int posY = 6;

	private boolean soletrando = false;
	private int tempoSoletra = 0;
	private int contSoletrar = 0;
	private String textoSoletrar;

	class Fade {
		public boolean fading = false;
		public int tempoFade = 0;
		public int tempoParaFade = 0;
		public int contIniFade = 0;
		public GroupLayer lyFade;
		public Callable funcAfterFade;
		
		public Fade(boolean fad, int tempoF, int tempoParaF, int cont, GroupLayer gLayer, Callable call) {
			fading = fad;
			tempoFade = tempoF;
			tempoParaFade = tempoParaF;
			contIniFade = cont;
			lyFade = gLayer;
			funcAfterFade = call;
		}
	}

	private LinkedList<Fade> listFadeOutPendente = new LinkedList<TextAvatar.Fade>();
	private LinkedList<Fade> listFadeInPendente = new LinkedList<TextAvatar.Fade>();

	class Soletra {
		public boolean hideOnTime;
		public String text;
		
		public Soletra(boolean hide, String txt) {
			hideOnTime = hide;
			text = txt;
		}
	}

	private LinkedList<Soletra> listSoletraPendente = new LinkedList<Soletra>();

    public TextAvatar(ScreenStack stack, GroupLayer layerBalao) {
    	_stack = stack;
    	gLayerBalao = layerBalao;
		tempoUltimaMessagem = 0;
    }

    @Override public void wasAdded () {
        super.wasAdded();
        _root = iface.createRoot(AxisLayout.vertical().gap(0).offStretch(), stylesheet(), layer);
        Background bgTransp = Background.solid(0xFF99CC66);
        _root.addStyles(Style.BACKGROUND.is(background()), Style.VALIGN.center);

        //_root.setSize(width(), height());
        //_root.setSize(100, 100);
        _root.setBounds(posX, posY, 180, 102);
        //_root.setVisible(false);

        //Background bg = Background.solid(0xFFCC99FF).inset(0, 0, 5, 0);
        /*
        _root.add(new Group(AxisLayout.horizontal(), Style.HALIGN.left, Style.BACKGROUND.is(bg)).add(
                      //this.back = new Button("Back"),
                      new Label(title()).addStyles(Style.FONT.is(TITLE_FONT), Style.HALIGN.center).
                      setConstraint(AxisLayout.stretched())));

        if (subtitle() != null) _root.add(new Label(subtitle()));
        */
        setVisible(false);
        Group iface = createIface();
        if (iface != null) _root.add(iface.setConstraint(AxisLayout.fixed()));
    }

    @Override public void wasRemoved () {
        super.wasRemoved();
        iface.destroyRoot(_root);
        while (layer.size() > 0) layer.get(0).destroy();
    }

    protected String name () {
        return "Label Test";
    }

    protected String title () {
        return "UI: Labels Test";
    }
    /** Returns an explanatory subtitle for this demo, or null. */
    protected String subtitle () { return null; }

    /** Override this method and return a group that contains your main UI, or null. */
    protected Group createIface () {
        Styles bigLabel = Styles.make(
            Style.FONT.is(PlayN.graphics().createFont("Helvetica", Font.Style.PLAIN, 18)),
            Style.VALIGN.center
        );

        lb = new Label(text);
        //lb = new Field(text);
        field = new Field("inicial");
        Background bgTransp = Background.blank();
        //Background bgTransp = Background.solid(0xFF99CC66);

        Group textGroup = new Group(AxisLayout.vertical().gap(5), Style.BACKGROUND.is(bgTransp)).add(
            					lb.addStyles(bigLabel)
            					//, new Shim(5, 2)
        	);
        lb.bounds(new Rectangle(0, 0, 178, 102));

        return textGroup;
    }

    public void prepareSetText(final String text, boolean hideOnTime) {
    	//Window.alert("dentro do prepareSetText");
    	if (!soletrando) {
    		this.hideOnTime = hideOnTime; 
    		prepareSetText(text);
    	} else {
    		//Agenda
    		listSoletraPendente.add(new Soletra(hideOnTime, text));
    	}
    }

    public void prepareSetText(final String text) {

    	int tamBreak = 18;

    	String[] palavras = text.split(" ");

    	int numLinhas = 0;
    	//String result = "\r\n";
    	//Window.alert("numLinhas = " + numBreaks);
    	String result = "";
    	int numLetrasNaLinha = 0;
    	for (int i = 0; i < palavras.length; i++) {
    		if (palavras[i].length() + numLetrasNaLinha > tamBreak) {
    			result += "\r\n";
    			numLinhas++;
    			numLetrasNaLinha = 0;
    		}
    		result += (result.equals("")?"":" ") + palavras[i];
    		numLetrasNaLinha += palavras[i].length() + 1;
    	}
    	result += "\r\n\r\n";
    	//Window.alert("dentro do setText");

    	if (numLinhas > 5) {
    		Styles newLabelStyle = Styles.make(
                Style.FONT.is(PlayN.graphics().createFont("Tahoma", Font.Style.PLAIN, 14)),
                Style.VALIGN.center);
    		lb.addStyles(newLabelStyle);
    		
    		/***********REFAZER AS LINHAS POIS A FONTE ESTA MENOR AGORA *************/
    		numLinhas = 0;

    		tamBreak = 28;
        	result = "";
        	numLetrasNaLinha = 0;
        	for (int i = 0; i < palavras.length; i++) {
        		if (palavras[i].length() + numLetrasNaLinha > tamBreak) {
        			result += "\r\n";
        			numLinhas++;
        			numLetrasNaLinha = 0;
        		}
        		result += (result.equals("")?"":" ") + palavras[i];
        		numLetrasNaLinha += palavras[i].length() + 1;
        	}
        	result += "\r\n\r\n";
        	/***********FIM - REFAZER AS LINHAS **************************************/
    		
    	}
    	
    	final String res = result;
    	//Window.alert("[" + res + "]");

    	this.text = text;
		tempoUltimaMessagem = 0;
    	//Window.alert("dentro do prepareSetText - isVisible:" + isVisible);
    	if (!isVisible || listFadeOutPendente.size() > 0) {
    		setText(""); 
    		if (_root != null && _root.layer != null) {
    			//Window.alert("Adicionando fadein...");
    			setVisible(true);
    			listFadeInPendente.add(new Fade(true, 0, menorTempoFade, 0, gLayerBalao, null));
    			listFadeInPendente.add(new Fade(true, 0, maiorTempoFade, 3, _root.layer, new Callable() {
    					public void call() {
    						soletraTexto(res);
    					}
	    			}
    			));
    			//Window.alert("Adicionou fadein ok");
    		} else {
    			//Window.alert("_root ou _root.layer null");
    			wasAdded();
    			//Window.alert("wasadded ok");
    			//Window.alert("_root ou _root.layer = null? resp = " + (_root == null || _root.layer == null));
    		}
    	} else {
    		soletraTexto(res);
    	}
    	//Window.alert("fim do prepareSetText");
    }

    private void soletraTexto(final String text) {
    	_root.layer.setVisible(true);
		tempoSoletra = 0;
		contSoletrar = 0;
		textoSoletrar = text;
		soletrando = true;
    }

    private void setText(String text) {
    	if (lb != null) {
    		if (lb.text != null) {
    			lb.text.update(text);
    		} else {
    			Window.alert("lb.text = " + lb.text);	
    		}
    	} else {
    		Window.alert("lb = " + lb);
    	}
		//Window.alert("passou no setText");
    	//TestePlayN.setMessageBox("Adicionou a mensagem texto:[" + text + "]");
    }

    public void fadeOut(Fade fad, float delta) {
    	if (fad.tempoFade >= fad.tempoParaFade) {
    		fad.tempoFade = 0;
			if (fad.contIniFade > 0) {
				fad.contIniFade -= 1;
				float f = ((float)fad.contIniFade/10f);
				//Window.alert("fadeout alpha = " + f);
				fad.lyFade.setAlpha(f);
				listFadeOutPendente.add(fad);
			}
		} else {
			fad.tempoFade += delta;
			listFadeOutPendente.add(fad);
		}
    }

    public void fadeIn(Fade fad, float delta) {
		if (fad.tempoFade >= fad.tempoParaFade) {
			fad.tempoFade = 0;
			if (fad.contIniFade < 10) {
				fad.contIniFade += 1;
				float f = ((float)fad.contIniFade/10f);
				//Window.alert("fadein alpha = " + f);
				fad.lyFade.setAlpha(f);
				listFadeInPendente.add(fad);
			} else {
			    //isVisible = true;
			    try {
			    	if (fad.funcAfterFade != null) {
			    		fad.funcAfterFade.call();
			    	}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
    	} else {
    		fad.tempoFade += delta;
    		listFadeInPendente.add(fad);
    	}		
    }

    /** Returns the stylesheet to use for this screen. */
    protected Stylesheet stylesheet () {
        return SimpleStyles.newSheet();
    }

    /** Returns the background to use for this screen. */
    protected Background background () {
    	return Background.blank();
        //return Background.bordered(0xFF4444FF, 0xFF2222FF, 1);
    }

    protected float updateRate () {
        return 16;
    }

    public int getPosX() {
    	return posX;
    }

    public int getPosY() {
    	return posY;
    }

    public void setPos(int x, int y) {
    	posX = x;
    	posY = y;
    	_root.setBounds(posX, posY, 180, 102);
    }

    public boolean getVisible() {
    	return isVisible;
    }

    public void setVisible(boolean visible) {
    	isVisible = visible;
    	if (_root != null && _root.layer != null) {
    		_root.layer.setVisible(visible);
    	}
    }

    public void myUpdate(float delta) {

    	//TestePlayN.setMessageBox("isVisible = " + isVisible + ", fadeIn size:" + listFadeInPendente.size());
    	if (listFadeOutPendente.size() > 0) {
			if (tempoUltimaMessagem >= tempoDisparaFadeOut) {
				//TestePlayN.setMessageBox("Disparando fadeOut!");
				fadeOut(listFadeOutPendente.removeFirst(), delta);

				if (listFadeOutPendente.size() == 0) {
					//TestePlayN.setMessageBox("fim do fadeout!");
					setVisible(false);
					//TestePlayN.setMessageBox("setou visible = false:" + isVisible);
				}

			} else {
				listFadeOutPendente.clear();
				setVisible(true);
			}

    	} else if (isVisible && hideOnTime && tempoUltimaMessagem >= tempoDisparaFadeOut) {
    		if (listFadeOutPendente.size() == 0) {
	    		//TestePlayN.setMessageBox("tempoUltimaMessagem disparado !");
				listFadeOutPendente.add(new Fade(true, 0, maiorTempoFade, 10, gLayerBalao, null));
				listFadeOutPendente.add(new Fade(true, 0, menorTempoFade, 10, _root.layer, null));
				//TestePlayN.setMessageBox("adicionou fades size=" + listFadeOutPendente.size());
    		}

    	} else if (listFadeInPendente.size() > 0) {
    		fadeIn(listFadeInPendente.removeFirst(), delta);

    	} else if (soletrando) {
    		if (tempoSoletra >= tempoParaSoletar) {
				if (contSoletrar < textoSoletrar.length()) {
					contSoletrar++;

					String s = textoSoletrar.substring(0, contSoletrar); 

					setText(s);
				} else {
					soletrando = false;
				}
    		} else {
    			tempoSoletra += delta;
    		}
    	} else if (listSoletraPendente.size() > 0) {
    		Soletra s = listSoletraPendente.removeFirst();
    		prepareSetText(s.text, s.hideOnTime);
    	}

		tempoUltimaMessagem += delta;
		//TestePlayN.setMessageBox("tempoUltimaMessagem = " + tempoUltimaMessagem);
    }
}